#include "utils.h"
#include <vector>
#include <stdarg.h>
#include "hlog.h"
namespace utils
{

std::string strToUpper(std::string str) {
	transform(str.begin(), str.end(), str.begin(), ::toupper);
	return str;
}

std::string strToLower(std::string str) {
	transform(str.begin(), str.end(), str.begin(), ::tolower);
	return str;
}

std::string getServerBySplit(const std::string& server) {
	char delimiter = ';';
	std::vector<std::string> tokens;
	std::string token;
	std::istringstream tokenStream(server);
	while (std::getline(tokenStream, token, delimiter))
	{
		tokens.push_back(token);
	}
	if (tokens.size() > 0) {
		return tokens[0];
	}
	return "";
}
		
std::vector<std::string> split(std::string src, std::string delimit){
	std::vector<std::string> vecSrc;
	auto last = 0;
	auto index = src.find_first_of(delimit, last);
	while (index != std::string::npos){
		vecSrc.push_back(src.substr(last, index - last));
		last = index + 1;
		index = src.find_first_of(delimit, last);
	}
	if (index - last > 0){
		vecSrc.push_back(src.substr(last, index - last));
	}
	return vecSrc;
}
int getProcessCount(std::string name,bool onlyJudgeRunning)
{
#ifdef _WIN32
	int count = 0;
	std::string str1("");
	DWORD pid = 0;
	HANDLE hSnapShot = NULL;
	PROCESSENTRY32 pInfo;
	pInfo.dwSize = sizeof(pInfo);
	pid = GetCurrentProcessId();
	hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hSnapShot)
	{
		goto _Exit_;
	}
	if (Process32First(hSnapShot, &pInfo)) {
		std::vector<long> proIds;
		std::vector<long> parProIds;
		do
		{
			str1 = std::string(pInfo.szExeFile);

			if (str1 == name)
			{
				if (onlyJudgeRunning) {
					count = 1;
					goto _Exit_;
				}
				proIds.push_back(pInfo.th32ProcessID);
				parProIds.push_back(pInfo.th32ParentProcessID);
			}
		} while (Process32Next(hSnapShot, &pInfo));
		for (auto proId : proIds) {
			std::vector<long>::iterator it;
			it = find(parProIds.begin(), parProIds.end(), proId);
			if (it != parProIds.end()) {
				++count;
			}
		}
	}
	CloseHandle(hSnapShot);
_Exit_:
	return count;
#endif
}

#ifdef _WIN32
#else
long long int GetDirectorySize(std::string dir)
{
	hlogd("GetDirectorySize");
	DIR *dp;
	struct dirent *entry;
	struct stat statbuf;
	long long int totalSize = 0;
	if ((dp = opendir(dir.c_str())) == NULL)
	{
		fprintf(stderr, "Cannot open dir: %s\n", dir.c_str());
		hlogd("Cannot open dir : %s", dir.c_str());
		return -1; //可能是个文件，或者目录不存在
	}
	//先加上自身目录的大小
	lstat(dir.c_str(), &statbuf);
	totalSize += statbuf.st_size;
	while ((entry = readdir(dp)) != NULL)
	{
		char* subdir = new char[1024]();
		sprintf(subdir, "%s/%s", dir.c_str(), entry->d_name);
		lstat(subdir, &statbuf);
		if (S_ISDIR(statbuf.st_mode))
		{
			if (strcmp(".", entry->d_name) == 0 ||
				strcmp("..", entry->d_name) == 0)
			{
				continue;
			}
			long long int subDirSize = GetDirectorySize(subdir);
			totalSize += subDirSize;
		}
		else
		{
			totalSize += statbuf.st_size;
		}
		delete []subdir;
	}
	closedir(dp);
	return totalSize;
}
#endif

bool isProcessRunningLinux(char *proc) {
#if defined(__linux__)
	FILE* fp = NULL;
	int count = 1;
	int BUFSZ = 100;
	char buf[BUFSZ];
	char command[150];
	
	sprintf(command, "pgrep -l %s$ |wc -l", proc);

	if ((fp = popen(command, "r")) == NULL)
	{
		return false;
	}
	if ((fgets(buf, BUFSZ, fp)) != NULL)
	{
		count = atoi(buf);
	}

	pclose(fp);

	fp = NULL;
	if (count  >= 1) {
		return true;
	}
	else {
		return false;
	}
#endif
	return false;
}


}
